import numpy as np
import matplotlib.pyplot as plt
import matplotlib as mpl
from sklearn.linear_model import LinearRegression
from sklearn.metrics import r2_score

# 设置全局字体配置
plt.rcParams['font.size'] = 10
plt.rcParams['font.sans-serif'] = ['SimHei', 'Microsoft YaHei', 'Arial Unicode MS']  # 多字体备选
plt.rcParams['axes.unicode_minus'] = False  # 正确显示负号
plt.rcParams['text.usetex'] = False  # 禁用LaTeX渲染
# 创建支持中文和数学符号的字体属性
chinese_font = mpl.font_manager.FontProperties(fname=mpl.font_manager.findfont('SimHei'))
math_font = mpl.font_manager.FontProperties(fname=mpl.font_manager.findfont('DejaVu Sans'))

# 实验数据
epsilon_values = [2, 5, 8, 10]

# MNIST数据集准确率 (%)
mnist_data = {
    "DP-FedAvg": [85.0, 92.3, 94.0, 94.5],
    "DP-AdaMod": [86.5, 93.7, 95.2, 95.8],
    "DP-FedANAW": [87.0, 94.2, 95.8, 96.3],
    "GP-AdaFL(our)": [89.0, 96.8, 97.5, 98.0]
}

# CIFAR-10数据集准确率 (%)
cifar10_data = {
    "DP-FedAvg": [61.5, 68.5, 72.0, 73.5],
    "DP-AdaMod": [63.0, 70.1, 73.5, 75.0],
    "DP-FedANAW": [64.5, 71.8, 74.5, 76.0],
    "GP-AdaFL(our)": [67.2, 74.3, 76.8, 78.0]
}

# 创建图形
fig, (ax1, ax2) = plt.subplots(2, 1, figsize=(6,8), dpi=100)

# 设置颜色和标记样式
colors = ['#1f77b4', '#ff7f0e', '#2ca02c', '#d62728']
markers = ['o', 's', '^', 'D']
line_styles = ['-', '--', '-.', ':']

# 绘制MNIST结果 - 移除数据点标注
for i, (method, accuracies) in enumerate(mnist_data.items()):
    ax1.plot(epsilon_values, accuracies, 
             label=method, 
             color=colors[i], 
             marker=markers[i], 
             linestyle=line_styles[i],
             linewidth=2,
             markersize=8)

# 设置MNIST子图属性

ax1.set_xlabel('隐私预算 (ε)', fontsize=11, fontproperties=chinese_font)
ax1.set_ylabel('测试准确率 (%)', fontsize=11, fontproperties=chinese_font)
ax1.set_xticks(epsilon_values)
ax1.set_ylim(80, 100)
# ax1.grid(True, linestyle='--', alpha=0.7)
ax1.legend(loc='lower right', prop=chinese_font, frameon=True, framealpha=0.9)
# 添加MNIST标题在子图下方
ax1.text(0.5, -0.25, '(a) MNIST数据集准确率随隐私预算变化', 
         fontsize=13, fontweight='bold', 
         ha='center', transform=ax1.transAxes, 
         fontproperties=chinese_font)


# 添加关键结论标注
ax1.annotate('GP-AdaFL在ε=2时保持89.0%准确率\n较DP-FedAvg提升3.5%', 
             xy=(2, 89), xytext=(3, 85),
             arrowprops=dict(arrowstyle='->', color='dimgray'),
             fontsize=7, fontproperties=chinese_font,
             bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="gray", alpha=0.8))

ax1.annotate('ε≥5时精度增益稳定在≥2.5%', 
             xy=(5, 96.8), xytext=(6, 93),
             arrowprops=dict(arrowstyle='->', color='dimgray'),
             fontsize=7, fontproperties=chinese_font,
             bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="gray", alpha=0.8))

# 绘制CIFAR-10结果 - 移除数据点标注
for i, (method, accuracies) in enumerate(cifar10_data.items()):
    ax2.plot(epsilon_values, accuracies, 
             label=method, 
             color=colors[i], 
             marker=markers[i], 
             linestyle=line_styles[i],
             linewidth=2,
             markersize=8)

# 设置CIFAR-10子图属性

ax2.set_xlabel('隐私预算 (ε)', fontsize=11, fontproperties=chinese_font)
ax2.set_ylabel('测试准确率 (%)', fontsize=11, fontproperties=chinese_font)
ax2.set_xticks(epsilon_values)
ax2.set_ylim(55, 80)
# ax2.grid(True, linestyle='--', alpha=0.7)
ax2.legend(loc='lower right', prop=chinese_font,fontsize=7 ,frameon=True, framealpha=0.9)
# 添加CIFAR-10标题在子图下方
ax2.text(0.5, -0.25, '(b) CIFAR-10数据集准确率随隐私预算变化', 
         fontsize=13, fontweight='bold', 
         ha='center', transform=ax2.transAxes, 
         fontproperties=chinese_font)


# 添加关键结论标注
ax2.annotate('低预算鲁棒性: ε=2时保持67.2%准确率\n较DP-FedAvg提升5.7%', 
             xy=(2, 67.2), xytext=(3, 62),
             arrowprops=dict(arrowstyle='->', color='dimgray'),
             fontsize=7, fontproperties=chinese_font,
             bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="gray", alpha=0.8))

ax2.annotate('动态噪声缩放避免过保护导致的性能损失', 
             xy=(8, 76.8), xytext=(6, 70),
             arrowprops=dict(arrowstyle='->', color='dimgray'),
             fontsize=7, fontproperties=chinese_font,
             bbox=dict(boxstyle="round,pad=0.3", fc="white", ec="gray", alpha=0.8))

# 添加整体标题
# fig.suptitle('图3：隐私-效用权衡分析', 
#              fontsize=16, fontweight='bold', 
#              fontproperties=chinese_font, y=0.95)

# 添加技术标注
fig.text(0.5, 0.01, 
         "实验设置: 总隐私预算ε_total=10 | Non-IID划分参数α=0.5 | 框架: GP-AdaFL", 
         ha="center", fontsize=11, style='italic', fontproperties=chinese_font)



# 调整布局并保存
plt.tight_layout(rect=[0, 0.03, 1, 0.95])
plt.savefig('privacy_utility_tradeoff.png', bbox_inches='tight', dpi=300)
plt.show()
